package request

import (
	"context"
	"encoding/json"
	"fmt"
	"go-micro.dev/v4/logger"
	"maya-service/collector/trace_log"
	"maya-service/constant"
	"maya-service/errors"
	"maya-service/model/po/mall"
	"maya-service/utils"
)

type UserData struct {
	UserName    string `json:"username"`
	WxwebOpenid string `json:"wxweb_openid"`
	Unionid     string `json:"unionid"`
	AvatarUrl   string `json:"avatar_url"`
}

type Ret struct {
	Code    int       `json:"code"`
	Msg     string    `json:"msg"`
	Success bool      `json:"success"`
	Data    *UserData `json:"data"`
}

type ShopUserData struct {
	MemberId       int    `json:"memberId"`
	MemberName     string `json:"memberName"`
	MemberNickName string `json:"memberNickName"`
	MemberAvatar   string `json:"memberAvatar"`
	UnionId        string `json:"unionid"`
}

// PushData 推送数据
func PushData(env string, userId, token string, url string, data interface{}) (err error) {
	configUrl := constant.TestConfigUrl + url
	if env == "prod" {
		configUrl = constant.ProdConfigUrl + url
	}

	sendData, _ := json.Marshal(data)
	rsp, err := DoRequest("POST", configUrl, string(sendData), map[string]string{
		"token":        token,
		"Content-Type": "application/json",
	})
	if err != nil {
		fmt.Println(err)
		return err
	}

	fmt.Println("-------------- 成功推送 PushData rsp:", utils.ToJsonString(rsp), "userId", userId, "token", token,
		"url", url, "data", utils.ToJsonString(data))

	type Ret1 struct {
		Code    int    `json:"code"`
		Msg     string `json:"msg"`
		Success bool   `json:"success"`
	}

	ret := &Ret1{}
	err = json.Unmarshal([]byte(rsp), ret)
	if err != nil {
		return err
	}

	if ret.Code != 0 {
		return fmt.Errorf(fmt.Sprintf("提现报错 userId:%v url:%v resp:%v", userId, url, utils.ToJsonString(ret)))
	}

	return nil
}

func Charge(env string, userId string, transId int64, delta float64) (err error) {
	configUrl := constant.TestConfigUrl + "/api/biz/ai/maya/updateBalance"
	if env == "prod" {
		configUrl = constant.ProdConfigUrl + "/api/biz/ai/maya/updateBalance"
	}

	type Req struct {
		Amount     float64 `json:"amount"`
		Tid        string  `json:"tid"`
		Remark     string  `json:"remark"`
		ActionType string  `json:"action_type"`
		UnionId    string  `json:"unionid"`
	}

	if env == "test" {
		delta = 0.01
	}
	data, _ := json.Marshal(&Req{
		Amount:     delta,
		Tid:        fmt.Sprintf("%v", transId),
		Remark:     "督导师提现",
		ActionType: "charge",
		UnionId:    userId,
	})
	rsp, err := DoRequest("POST", configUrl, string(data), map[string]string{
		"Authorization": "9650e3c2-e02c-4d8e-80b8-83461095a457",
		"Content-Type":  "application/json",
	})
	if err != nil {
		fmt.Println(err)
		return err
	}

	type Ret1 struct {
		Code    int    `json:"code"`
		Msg     string `json:"msg"`
		Success bool   `json:"success"`
	}

	ret := &Ret1{}
	err = json.Unmarshal([]byte(rsp), ret)
	if err != nil {
		return err
	}

	if ret.Code != 0 {
		return fmt.Errorf(fmt.Sprintf("提现报错 userId:%v transId:%v resp:%v", userId, transId, utils.ToJsonString(ret)))
	}

	return nil
}

// GetUserDataByToken 根据用户token查询用户信息
func GetUserDataByToken(token string, env string, unionId string) (*UserData, error) {
	configUrl := constant.TestConfigUrl + "/api/biz/ai/maya/queryUserInfo"
	if env == "prod" {
		configUrl = constant.ProdConfigUrl + "/api/biz/ai/maya/queryUserInfo"
	}

	if unionId != "" {
		configUrl = fmt.Sprintf("%v?unionid=%v", configUrl, unionId)
	}
	rsp, err := DoRequest("GET", configUrl, "", map[string]string{
		"token": token,
	})
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	ret := &Ret{}
	err = json.Unmarshal([]byte(rsp), ret)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	return ret.Data, nil
}

// GetStoreInfo 查询商店信息
func GetStoreInfo(token string, env string) (productInfo mall.StoreInfo, err error) {
	configUrl := constant.TestShopConfigUrl + "/v3/seller/seller/store/indexStoreInfor"
	if env == "prod" {
		configUrl = constant.ProdShopConfigUrl + "/v3/seller/seller/store/indexStoreInfor"
	}

	rsp, err := DoRequest("GET", configUrl, "", map[string]string{
		"Authorization": token,
		"content-type":  "application/json;charset=utf-8",
	})

	if err != nil {
		fmt.Println(err)
		return
	}

	// 最外层 JSON 结构
	type Response struct {
		Data      mall.StoreInfo `json:"data"`
		LogMsg    *string        `json:"logMsg"`
		Msg       string         `json:"msg"`
		State     int            `json:"state"`
		Timestamp int64          `json:"timestamp"`
	}

	ret := &Response{}
	err = json.Unmarshal([]byte(rsp), ret)
	if err != nil {
		fmt.Println(err)
		return
	}

	return ret.Data, nil
}

// GetProductInfo 查询sku
func GetProductInfo(token string, env string, productId int64) (productInfo mall.GoodsInfo, err error) {
	configUrl := constant.TestShopConfigUrl + "/v3/goods/front/goods/productInfo"
	if env == "prod" {
		configUrl = constant.ProdShopConfigUrl + "/v3/goods/front/goods/productInfo"
	}

	if productId > 0 {
		configUrl = fmt.Sprintf("%v?productId=%v", configUrl, productId)
	}

	rsp, err := DoRequest("GET", configUrl, "", map[string]string{
		"authority":       configUrl,
		"authorization":   token,
		"language":        "zh",
		"terminal-source": "2",
		"content-type":    "application/x-www-form-urlencoded",
	})

	if err != nil {
		fmt.Println(err)
		return
	}

	// 最外层 JSON 结构
	type Response struct {
		Data      mall.GoodsInfo `json:"data"`
		LogMsg    *string        `json:"logMsg"`
		Msg       string         `json:"msg"`
		State     int            `json:"state"`
		Timestamp int64          `json:"timestamp"`
	}

	ret := &Response{}
	err = json.Unmarshal([]byte(rsp), ret)
	if err != nil {
		fmt.Println(err)
		return
	}

	return ret.Data, nil
}

// GetUserMemberInfo 获取成员信息
func GetUserMemberInfo(token string, env string) (*UserData, error) {
	prefix := constant.TestShopConfigUrl
	configUrl := constant.TestShopConfigUrl + "/v3/member/front/member/memberInfo"
	if env == "prod" {
		prefix = constant.ProdShopConfigUrl
		configUrl = constant.ProdShopConfigUrl + "/v3/member/front/member/memberInfo"
	}

	rsp, err := DoRequest("GET", configUrl, "", map[string]string{
		"authority":       prefix,
		"authorization":   token,
		"language":        "zh",
		"terminal-source": "2",
		"content-type":    "application/x-www-form-urlencoded",
	})

	trace_log.CommonLogger.Info(" ###### GetUserMemberInfo url:", configUrl, "token:", token, " rsp:", rsp, " err:", err)
	if err != nil {
		return nil, err
	}

	type RetData struct {
		State int           `json:"state"`
		Data  *ShopUserData `json:"data"`
	}

	//trace_log.CommonLogger.Info("#### GetUserMemberInfo rsp:", rsp, "err:", err)
	ret := &RetData{}
	err = json.Unmarshal([]byte(rsp), ret)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	if ret.Data == nil {
		return nil, fmt.Errorf("data is nil")
	}

	unionId := fmt.Sprintf("%v", ret.Data.MemberId)
	if ret.Data.UnionId != "" {
		unionId = ret.Data.UnionId
	}

	return &UserData{
		UserName:    ret.Data.MemberName,
		WxwebOpenid: "",
		Unionid:     unionId,
		AvatarUrl:   ret.Data.MemberAvatar,
	}, nil
}

func GetUserId(ctx context.Context) (string, error) {
	var (
		userId string
		err    error
	)

	value := ctx.Value(constant.UserId)
	userId, ok := value.(string)
	if !ok {
		if value != nil {
			logger.Errorf("context user id type err %T", value)
		}
		return userId, errors.New("token err")
	}
	return userId, err
}

func GetUserData(ctx context.Context) (*UserData, error) {
	var (
		err error
	)

	value := ctx.Value(constant.UserData)
	_, ok := value.(*UserData)
	if !ok {
		return &UserData{}, errors.New("token err")
	}
	return value.(*UserData), err
}
